from django.shortcuts import render, redirect
from django.contrib import messages
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from .models import Question, Subject
import pandas as pd
from docx import Document
import os
import re
from datetime import datetime
from PIL import Image  # 用于图片拼接
from django.db.models import Max

def index(request):
    """考试系统首页视图"""
    context = {
        'title': '考试系统',
        'questions': Question.objects.all()[:10]  # 获取最近的10个题目
    }
    return render(request, 'exam_system/index.html', context)




# 获取科目拼音
def get_subject_pinyin(subject_id):
    # 假设科目名称可以通过subject_id从其他表或字典中获取
    # 这里简单返回subject_id的字符串形式
    return str(subject_id)

# 判断题型
def determine_question_type(options, answer):
    if not options[0]:
        return 'judge'
    elif len(answer) == 1:
        return 'single'
    else:
        return 'multiple'

# 从数据库中读取exam_system_question 表中的最大id值
def get_max_id():
    # 使用aggregate方法获取最大id
    max_id = Question.objects.aggregate(max_id=Max('id'))['max_id']

    # 如果表中没有数据，max_id可能是None
    if max_id is None:
        max_id = 0  # 或者其他默认值
    return max_id

# 横向拼接多张图片
def combine_images_horizontally(image_paths, output_path):
    images = [Image.open(path) for path in image_paths]
    widths, heights = zip(*(img.size for img in images))

    total_width = sum(widths)
    max_height = max(heights)

    combined_image = Image.new('RGB', (total_width, max_height))

    x_offset = 0
    for img in images:
        combined_image.paste(img, (x_offset, 0))
        x_offset += img.size[0]

    combined_image.save(output_path)
    return output_path

# 从Word文件导入题库
def import_from_word(file_path, subject_id):
    doc = Document(file_path)
    print(doc)
    total_imported = 0
    type_counts = {'单选': 0, '多选': 0, '判断': 0}
    subject_pinyin = get_subject_pinyin(subject_id)
    image_folder = './media/question_images'
    # os.makedirs(image_folder, exist_ok=True)  # 创建图片保存文件夹

    current_question = None
    current_options = []
    current_answer = None
    current_image_paths = []  # 存储多张图片路径
    question_number = get_max_id()  # 从数据库中读取exam_system_question 表中的最大id值

    # 遍历Word文档中的每一个段落
    for para in doc.paragraphs:
        text = para.text.strip()

        # 处理图片
        if para.runs and para.runs[0].text == '' and para.runs[0].element.xpath('.//w:drawing'):
            image_name = f'{subject_pinyin}_{question_number}_{len(current_image_paths) + 1}.png'
            image_path = os.path.join(image_folder, image_name)
            for shape in para._element.xpath('.//w:drawing'):
                blip = shape.xpath('.//a:blip/@r:embed')[0]
                image_part = doc.part.related_parts[blip]
                with open(image_path, 'wb') as f:
                    f.write(image_part.blob)
            current_image_paths.append(image_path)
            print(f"当前图片路径：{image_path}")
            continue

        if not text:
            continue

        # 题干行
        if re.match(r'^\.?\d+\s+', text):
            current_question = text
            print(f"当前题干：{current_question}")
            continue

        # 选项行（以A.、B.、C.等开头）
        if re.match(r'^[A-Z]\.', text):
            current_options.append(text)
            # print(f"当前选项：{text}")
            continue

        # 答案行（以“答案：”开头）
        if text.startswith('答案：'):
            current_answer = text.replace('答案：', '').strip()
            # print(f"当前答案：{current_answer}")


        # 题目结束，插入数据库
        if current_question and current_answer:
            options_str = '\n'.join(current_options) if current_options else ''
            question_type = determine_question_type(current_options, current_answer)
            difficulty = 'medium'  # 默认难度
            current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

            # 处理多张图片
            if len(current_image_paths) > 1:
                combined_image_name = f'{subject_pinyin}_{question_number}_combined.png'
                combined_image_path = os.path.join(image_folder, combined_image_name)
                combine_images_horizontally(current_image_paths, combined_image_path)
                final_image_path = combined_image_path
            elif len(current_image_paths) == 1:
                final_image_path = current_image_paths[0]
            else:
                final_image_path = None

            Question.objects.create(
                subject_id=subject_id,
                content=current_question,
                question_type=question_type,
                options=options_str,
                answer=current_answer,
                difficulty=difficulty,
                image=final_image_path,
                create_time=current_time,
                update_time=current_time
            )

            question_number += 1
            total_imported += 1
            type_counts[question_type] += 1

        # 重置当前题目信息,无论是否添加成功，都要清空
        current_question = None
        current_options = []
        current_answer = None
        current_image_paths = []

    return f"从Word文件导入完成，共导入{total_imported}题。" + f"题型分布：单选{type_counts['单选']}题，多选{type_counts['多选']}题，判断{type_counts['判断']}题。"

# 从Excel文件导入题库
# def import_from_excel(file_path):
#     df = pd.read_excel(file_path)
#     total_imported = 0
#     type_counts = {'单选': 0, '多选': 0, '判断': 0}
#
#     for index, row in df.iterrows():
#         question = row.get('题干')
#         options = row.get('选项', '')
#         answer = row.get('答案')
#         difficulty = row.get('难度', '中')
#         image = row.get('图片', '')
#
#         if not question or not answer:
#             continue
#
#         question_type = determine_question_type(options, answer)
#         current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
#
#         cursor.execute('''
#         INSERT INTO exam_system_question (subject_id, question, question_type, options, answer, difficulty, image, create_time, update_time)
#         VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
#         ''', (subject_id, question, question_type, options, answer, difficulty, image, current_time, current_time))
#
#         total_imported += 1
#         type_counts[question_type] += 1
#
#
#     return f"从Excel文件导入完成，共导入{total_imported}题。" + f"题型分布：单选{type_counts['单选']}题，多选{type_counts['多选']}题，判断{type_counts['判断']}题。"
#












def import_questions(request):
    if request.method == 'POST' and request.FILES.get('file'):
        file = request.FILES['file']
        file_extension = os.path.splitext(file.name)[1].lower()

        if file_extension not in ['.xlsx', '.xls', '.docx']:
            messages.error(request, '不支持的文件格式。请上传 Excel 或 Word 文件。')
            return redirect('exam_system:import_questions')

        # 保存上传的文件
        file_path = default_storage.save(f'temp/{file.name}', ContentFile(file.read()))

        try:
            subject, _ = Subject.objects.get_or_create(name= request.POST.get('subject'))
            if file_extension in ['.xlsx', '.xls']:
                questions = parse_excel(file_path)
                # 导入试题
                for question_data in questions:
                    Question.objects.create(
                        subject=subject,
                        content=question_data['content'],
                        question_type=question_data['question_type'],
                        options=question_data['options'],
                        answer=question_data['answer'],
                        difficulty=question_data['difficulty']
                    )
                messages.success(request, f'成功导入 {len(questions)} 道试题。')
            else:
                result = import_from_word(file_path)


        except Exception as e:
            messages.error(request, f'导入失败：{str(e)}')
        finally:
            # 删除临时文件
            default_storage.delete(file_path)

        return redirect('exam_system:import_questions')

    return render(request, 'exam_system/import_questions.html')

def parse_excel(file_path):
    df = pd.read_excel(file_path)
    questions = []
    for _, row in df.iterrows():
        questions.append({
            'subject': row['科目'],
            'content': row['题干'],
            'question_type': row['题型'],
            'options': row['选项'],
            'answer': row['答案'],
            'difficulty': row['难度']
        })
    return questions
